<template>
  <div class="form-detail">
    <fks-form
      ref="form"
      :model="tableForm"
      :rules="rules"
      inline-message
      v-bind="$attrs"
    >
      <div class="table-theader">
        <span class="theader-name">
          <i
            style="vertical-align: middle; margin-right: 8px; font-size: 16px"
            class="fks-icon-text"
          />
          <span>{{ tableName }}</span>
        </span>
        <span
          v-if="!readonly"
          class="theader-btn"
        >
          <fks-button
            type="plain"
            icon="fks-icon-plus"
            @click="add"
          >
            {{ LANG.ADD }}
          </fks-button>
          <fks-button
            type="plain"
            icon="fks-icon-delete"
            size="small"
            :disabled="chosedData.length == 0"
            @click="deletField"
          >
            {{ LANG.DELETE }}
          </fks-button>
        </span>
      </div>
      <fks-table
        ref="detailTable"
        :data="tableForm.tableData"
        v-bind="$attrs"
        highlight-current-row
        border
        row-key="dragId"
        v-on="$listeners"
        @selection-change="handleChange"
      >
        <!--        <fks-table-column width="14">-->
        <!--          <span class="moveBtn"></span>-->
        <!--        </fks-table-column>-->
        <fks-table-column
          v-if="!readonly"
          width="50"
          type="selection"
          align="center"
        />
        <fks-table-column
          width="50"
          type="index"
          align="center"
          label="#"
        />
        <fks-table-column
          v-for="(item, index) in tableColumnTemp"
          :key="index"
          :fixed="item.fixed"
          :label="item.label"
          v-bind="item.tableColumnProps"
        >
          <template v-slot="slotProps">
            <fks-form-item
              :prop="'tableData.' + slotProps.$index + '.' + item.prop"
              :rules="mergeRules(rules[item.prop], item.rules)"
              v-bind="item.formItemProps"
            >
              <slot
                :name="item.prop"
                :col="item"
                :row="slotProps.row"
              >
                <FormUpload
                  v-if="item.editType === 'upload'"
                  v-model="slotProps.row[item.prop]"
                  :disabled="readonly || item.readonly"
                  :file-list.sync="
                    slotProps.row[item.filesProp || item.prop + 'Files']
                  "
                  :files.sync="slotProps.row[item.files]"
                  v-bind="dealWith(item)"
                  v-on="item.listeners"
                />
                <fks-select
                  v-else-if="item.editType === 'select'"
                  v-model="slotProps.row[item.prop]"
                  clearable
                  :readonly="readonly || item.readonly"
                  v-bind="item"
                  v-on="item.listeners"
                >
                  <fks-option
                    v-for="option in item.options"
                    :key="option.value"
                    :label="option.label"
                    :value="option.value"
                  />
                </fks-select>
                <fks-date-picker
                  v-else-if="item.editType === 'datePicker'"
                  v-model="slotProps.row[item.prop]"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  type="date"
                  :readonly="readonly || item.readonly"
                  v-bind="item"
                  v-on="item.listeners"
                />
                <fks-user-selector
                  v-else-if="item.editType === 'user'"
                  style="width: 100%"
                  :username.sync="slotProps.row[item.username]"
                  :userfullname.sync="slotProps.row[item.prop]"
                  :readonly="readonly || item.readonly"
                  v-bind="item"
                  v-on="item.listeners"
                />
                <fks-org-selector
                  v-else-if="item.editType === 'dept'"
                  style="width: 100%"
                  :dept-id.sync="slotProps.row[item.deptId]"
                  :dept-name.sync="slotProps.row[item.prop]"
                  :readonly="readonly || item.readonly"
                  v-bind="item"
                  v-on="item.listeners"
                />
                <fks-input
                  v-else-if="item.editType === 'textarea'"
                  v-model="slotProps.row[item.prop]"
                  type="textarea"
                  :rows="item.rows ? item.rows : 3"
                  :readonly="readonly || item.readonly"
                  v-bind="item"
                  v-on="item.listeners"
                />
                <fks-input
                  v-else
                  v-model="slotProps.row[item.prop]"
                  :readonly="readonly || item.readonly"
                  v-bind="item"
                  v-on="item.listeners"
                />
              </slot>
            </fks-form-item>
          </template>
        </fks-table-column>
      </fks-table>
    </fks-form>
  </div>
</template>

<script>
import FormUpload from '@/modules/FormCenter/components/FormUpload'
import Sortable from 'sortablejs'
import emitter from 'fawkes-lib/src/mixins/emitter'
export default {
  name: 'FormDetail',
  componentName: 'FormDetail',
  components: {
    FormUpload
  },
  mixins: [emitter],
  props: {
    tableColumn: {
      type: Array,
      default: () => {
        return []
      }
    },
    formDetail: {
      type: Array,
      default: () => {
        return []
      }
    },
    tableName: {
      type: String,
      default: ''
    },
    readonly: {
      type: Boolean,
      default: false
    },
    rules: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      sortable: null,
      chosedData: [],
      formDetailTemp: this.formDetail.map((item, index) => {
        const obj = {}
        Object.keys(item).forEach((key) => {
          obj[key] = item[key]
        })
        obj.dragId = index
        obj.deleteFlag = '0'
        return obj
      }),
      flag: false
    }
  },
  computed: {
    tableForm() {
      return {
        tableData:
          this.formDetailTemp.filter((item) => {
            return item.deleteFlag == '0'
          }) || []
      }
    },
    tableColumnTemp() {
      return this.tableColumn.filter((item) => {
        return !item.hidden
      })
    }
  },
  watch: {
    formDetail: {
      handler(val) {
        this.flag = true
        this.formDetailTemp = val.map((item, index) => {
          const obj = {}
          Object.keys(item).forEach((key) => {
            obj[key] = item[key]
          })
          obj.deleteFlag || (obj.deleteFlag = '0')
          obj.dragId = index
          return obj
        })
        // this.setSort()
      },
      deep: true
    },
    formDetailTemp: {
      handler(val) {
        if (!this.flag) {
          this.$emit(
            'update:formDetail',
            val.map((item, index) => {
              item.dragId = index
              const temp = Object.assign({}, item)
              return temp
            })
          )
        }
        this.flag = false
      },
      deep: true
    }
  },
  created() {
    this.$on('validateForm', () => {
      this.$refs.form.validate((valid) => {
        this.dispatch('FormCenter', 'FormDetailValidate', valid)
      })
    })
  },
  methods: {
    // 拖拽
    setSort() {
      const el = this.$refs.detailTable.$el.querySelectorAll(
        '.fks-table__body-wrapper > table > tbody'
      )[0]
      this.sortable = Sortable.create(el, {
        handle: '.moveBtn',
        chosenClass: '',
        ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
        filter: '.ignore-elements', // 选择不支持拖动的选择器
        setData: function (dataTransfer) {
          // to avoid Firefox bug
          // Detail see : https://github.com/RubaXa/Sortable/issues/1012
          dataTransfer.setData('Text', '')
        },
        onStart: function (/**Event*/ evt) {
          evt.oldIndex // element index within parent
        },
        onChange: function (/**Event*/ evt) {
          // console.log('移动中', evt.newIndex) // most likely why this event is used is to get the dragging element's current index
          // same properties as onEnd
        },
        onEnd: (evt) => {
          this.tableForm.tableData.splice(
            evt.newIndex,
            0,
            this.tableForm.tableData.splice(evt.oldIndex, 1)[0]
          )
          // console.log(evt.oldIndex)
          // console.log(evt.newIndex)
          const newArray = this.tableForm.tableData.slice(0)
          // this.$refs.detailTable.clearSort()
          this.tableForm.tableData = [] // 拖动处理完毕后进行保存
          this.$nextTick(function () {
            this.tableForm.tableData = newArray
            if (this.isEditing()) {
              this.saveDetail()
            }
          })
        }
      })
    },
    isEditing() {
      let flag = true
      this.tableForm.tableData.forEach((item) => {
        if (item.type == 'edit') {
          flag = false
        }
      })
      return flag
    },
    saveDetail() {
      this.formDetailTemp = this.tableForm.tableData
    },
    add() {
      let tempObj = {}
      for (let i = 0; i < this.tableColumn.length; i++) {
        const item = this.tableColumn[i]
        tempObj[item.prop] = item.defaultValue || ''
        if (item.editType === 'user') {
          tempObj[item.username] = item.usernameDefaultValue
        } else if (item.editType === 'dept') {
          tempObj[item.deptId] = item.deptIdDefaultValue
        }
      }
      tempObj.deleteFlag = '0'
      this.flag = false
      this.formDetailTemp.push(tempObj)
    },
    deletField() {
      for (let i = 0; i < this.chosedData.length; i++) {
        this.chosedData[i].deleteFlag = '-1'
      }
    },
    handleChange(val) {
      this.chosedData = val
    },
    dealWith(item) {
      let TempItem = JSON.parse(JSON.stringify(item))
      delete TempItem.files
      return TempItem
    },
    mergeRules(rules1 = [], rules2 = []) {
      return rules1.concat(rules2)
    }
  }
}
</script>

<style lang="scss" scoped>
.form-detail {
  margin-bottom: 22px;
  //  ::v-deep  .fks-table--enable-row-hover .fks-table__body tr:hover > td {
  //   background-color: #fff;
  // }
  ::v-deep .fks-form-item {
    margin-bottom: 0;
  }

  .table-theader {
    margin-bottom: 16px;

    .theader-name {
      display: inline-block;
      height: 36px;
      font-weight: bold;
      line-height: 36px;

      span {
        font-size: 14px;
        color: #191919;
      }
    }

    .theader-btn {
      float: right;
    }
  }

  ::v-deep .fks-form-item__content {
    margin: 10px 0 !important;
  }

  ::v-deep .fks-table__empty-text {
    color: #999;
  }

  .moveBtn {
    display: block;
    width: 3px;
    height: 22px;
    margin: 0 -11px;
    border: 1px dotted #adadad;
    cursor: move;
  }
}

.sortable-ghost {
  color: #fff !important;
  background: #81baff !important;
  opacity: 0.8;
}

::v-deep .fks-button--medium {
  min-width: 72px;
  height: 32px;
  padding: 0;
}

::v-deep .fks-button--small {
  min-width: 72px;
  height: 32px;
  padding: 0;
}
</style>
